// 1190. [栈DFS]删除整个目录.中 https://oj.rnd.huawei.com/problems/1190/details
// 【案例开放007】0918
// http://3ms.huawei.com/km/groups/3803117/blogs/details/9139131?l=zh-cn
// 目录结构字符串(类似Windows的tree/f的输出内容)，用它来表达目录树的结构
// 目录结构字符串的输入仅含数字、字母和|-，其中：|-
// 表示子目录的层次符号；字母或数字表示目录名。
// 某目录的子目录的顺序以输入先后顺序为准。
// 某目录的多个子目录不能同名，如果出现多个，则只保留第一个，后续的输入忽略。
// 无对应的父目录，属于异常情况，直接忽略。
// 给定一个目录结构字符串，请按先后顺序删除所有目录，并依次输出删除的目录名称：
// 如果是叶子目录，直接删除。
// 如果某目录含有子目录，则需要先删除其子目录。
//  样例1解释：
//  |-B     // 非顶层目录，并且它前面无对应的父目录，该行输入被忽略
//  A       // A为顶层目录
//  |-B     // B为第二层，它紧跟的上一层目录为A，因此B为A的子目录
//  |-|-C     // C为第三层，它紧跟的上一层目录为B，因此其父目录为B。
//  |-|-D     //
//  D为第三层，它紧跟的上一层目录为B，因此其父目录为B，它和C为兄弟关系。
//  |-|-D     // D为第三层，与先输入的第三层目录D同名，该行输入被忽略。
//  |-|-|-|-D   //
//  D为第五层，前面没有第四层目录，因此无对应的父目录，该行输入被忽略。
//  |-|-E       //
//  E为第三层，它紧跟的上一层目录为B，因此其父目录为B，它和C、D为兄弟关系。
//  |-|-|-F     // F为第四层，它紧跟的上一层目录为E，因此其父目录为E。
//  |-lib32     //
//  lib32为第二层，它紧跟的上一层目录为A，因此其父目录为A，它与B为兄弟关系。
// =================================
// 20
// |-B
// A
// |-B
// |-|-C
// |-|-D
// |-|-D
// |-|-|-|-D
// |-|-E
// |-|-|-F
// |-lib32
// |-B
// Q
// |-R
// |-|-W
// |-|-W
// |-|-T
// |-|-|-|-I
// |-|-P
// |-|-|-J
// |-lib64
// C D F E B lib32 A W T J P R lib64 Q
//  ------------
// 23
// 0
// |-1
// |-|-3
// |-|-|-4
// |-|-|-|-5
// |-|-|-|-|-6
// |-|-|-|-|-|-7
// |-|-|-|-|-|-|-A
// |-|-|-|-|-|-7
// |-|-|-|-|-|-|-A
// |-|-|-|-|-|-8
// |-|-|-|-|-|-|-9
// |-|-|-|-|-|-8
// |-|-|-|-|-|-|-9
// |-|-|-|-F
// |-|-|-|-|-9
// |-|-|-|-|-|-H
// |-|-|-|-|-|-|-8888888888
// |-|-D
// |-|-E
// |-|-|-7777777777
// |-|-|-|-E
// |-G
// A 7 9 8 6 5 8888888888 H 9 F 4 3 D E 7777777777 E 1 G 0

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Solution {
 public:
  int deep(const string& s) {
    return std::count_if(s.begin(), s.end(), [](char c) { return c == '-'; });
  }

  vector<string> DelAllDirectorys(const vector<string>& dirTreeLines) {
    vector<string> result;
    stack<string> stkNode;
    map<int, set<string>> mapTree;  // 对应level级别的节点名称集合,判重
    for (auto sNode : dirTreeLines) {
      int curNodeDepth = deep(sNode);
      // 级别对应的同名节点已经存在
      if (mapTree[curNodeDepth].find(sNode) != mapTree[curNodeDepth].end()) {
        continue;
      }
      // 栈空
      if (stkNode.empty()) {
        // 根节点进栈
        if (curNodeDepth == 0) {
          stkNode.push(sNode);
          mapTree[curNodeDepth].insert(sNode);
        }
      } else {
        // 当前节点是下一级,进栈
        if (curNodeDepth == deep(stkNode.top()) + 1) {
          mapTree[curNodeDepth].insert(sNode);
          stkNode.push(sNode);
          // 当前节点是同级或上级
        } else if (curNodeDepth <= deep(stkNode.top())) {
          // sNode.c_str());
          // 栈里的下级节点出栈,保存结果.对应级的节点清空
          while (curNodeDepth < deep(stkNode.top())) {
            result.push_back(stkNode.top());
            mapTree[deep(stkNode.top())].clear();
            stkNode.pop();
          }
          // sNode.c_str()); 栈顶同级节点出栈,保存结果
          result.push_back(stkNode.top());
          stkNode.pop();
          // 当前同级节点进栈
          mapTree[curNodeDepth].insert(sNode);
          stkNode.push(sNode);
        }
      }
    }
    while (!stkNode.empty()) {
      result.push_back(stkNode.top());
      stkNode.pop();
    }
    // 获取节点名称
    for (int i = 0; i < result.size(); i++)
      result[i] = result[i].substr(2 * deep(result[i]));
    return result;
  }
};

// ==============================
// 以下为考题输入输出框架，此部分代码不建议改动
inline string ReadLine() {
  string line;
  getline(cin, line);
  return line;
}

inline vector<string> ReadLines(int size) {
  vector<string> lines(size);
  for (int i = 0; i < size; ++i) {
    lines[i] = ReadLine();
  }
  return lines;
}

inline vector<string> ReadCountedLines() {
  string numberLine = ReadLine();
  int count = stoi(numberLine);
  return ReadLines(count);
}

template <typename T>
inline void WriteVector(const vector<T>& objects, char delimeter = ' ') {
  auto it = objects.begin();
  if (it == objects.end()) {
    return;
  }
  cout << *it;
  for (++it; it != objects.end(); ++it) {
    cout << delimeter << *it;
  }
  cout << endl;
}

int main() {
  vector<string> dirTreeLines = ReadCountedLines();
  Solution solu;
  auto delDirs = solu.DelAllDirectorys(dirTreeLines);
  WriteVector(delDirs);

  return 0;
}
